SPB Git

Repository Public

page.tsx 1.8 KB 32 lines tsx

1import type { Metadata } from "next";2import { FilmGrid } from "@/components/FilmCard";3import { searchFilms } from "@/lib/films";4import { dict, href, type Locale } from "@/lib/i18n";56export async function generateMetadata({ params }: { params: Promise<{ locale: string }> }): Promise<Metadata> {7  const locale = (await params).locale as Locale;8  return { title: dict(locale).search.title, robots: { index: false }, alternates: { canonical: href(locale, "/search") } };9}1011export default async function Search({ params, searchParams }: { params: Promise<{ locale: string }>; searchParams: Promise<{ q?: string }> }) {12  const locale = (await params).locale as Locale;13  const q = ((await searchParams).q ?? "").slice(0, 120);14  const t = dict(locale);15  const hits = q ? await searchFilms(locale, q) : [];16  return (17    <div className="py-10">18      <h1 className="display text-5xl md:text-6xl">{t.search.title}</h1>19      <form action={href(locale, "/search")} role="search" className="mt-6 flex max-w-2xl gap-2">20        <label htmlFor="q" className="sr-only">{t.search.title}</label>21        <input id="q" name="q" type="search" defaultValue={q} placeholder={t.search.placeholder} className="field" autoComplete="off" maxLength={120} />22        <button type="submit" className="btn btn-primary">{t.search.button}</button>23      </form>24      <p className="mt-3 text-sm text-[var(--color-faint)]">{t.search.hint}</p>25      <div className="mt-8" aria-live="polite">26        {q && !hits.length && <p className="card p-8 text-[var(--color-muted)]">{t.search.none}</p>}27        {hits.length > 0 && <FilmGrid films={hits.map((h) => h.film)} locale={locale} notes={Object.fromEntries(hits.map((h) => [h.film.id, `${t.search.matched}: ${h.signals.join(", ")}`]))} />}28      </div>29    </div>30  );31}32
Files main
Menu

Theme